package com.amt.olcacon.utils;


import org.openlca.core.DataDir;
import org.openlca.core.database.IDatabase;
import org.openlca.core.database.ImpactMethodDao;
import org.openlca.core.database.ProcessDao;
import org.openlca.core.math.SystemCalculator;
import org.openlca.core.matrix.index.EnviFlow;
import org.openlca.core.matrix.index.ImpactIndex;
import org.openlca.core.matrix.index.TechFlow;
import org.openlca.core.model.CalculationSetup;
import org.openlca.core.model.Process;
import org.openlca.core.model.descriptors.ImpactDescriptor;
import org.openlca.core.results.LcaResult;

import java.util.ArrayList;
import java.util.List;

import static org.eclipse.persistence.jpa.jpql.Assert.fail;

/**
 * 测试类，用于展示TreeItem类的注释信息并结合计算结果
 */
public class TreeItemAll {

    private final IDatabase db = DataDir.get().openDatabase("ecoinvent 3.11 Cutoff System-Processes 2025-01-31");
    private final String PROCESS_UUID = "e9c89a4e-2582-47ea-955f-480bf981785d";

    /**
     * 测试展示TreeItem类的注释信息
     */

    public void testShowTreeItemComment() {
        // 1. 从数据库中查找指定UUID的过程
        ProcessDao processDao = new ProcessDao(db);
        Process process = processDao.getForRefId(PROCESS_UUID);


        // 获取影响方法
        var method = new ImpactMethodDao(db).getForId(64262565L);

        // 2. 设置计算配置
        CalculationSetup setup = CalculationSetup.of(process).withImpactMethod(method);

        // 3. 执行核算
        SystemCalculator calculator = new SystemCalculator(db);
        LcaResult result = null;

        try {
            result = calculator.calculate(setup);



            // 简要展示计算结果信息
            System.out.println("\n计算结果概览：");
            System.out.println("- 过程名称: " + process.name);
            System.out.println("- 影响类别数量: " + result.impactIndex().size());

            // 如果有影响类别，构建三层级影响贡献树
            if (!result.impactIndex().isEmpty()) {
                // 遍历获取第一个影响类别
                for (ImpactDescriptor impact : result.impactIndex()) {
                    double totalValue = result.getTotalImpactValueOf(impact);
                    System.out.println("- 影响类别: " + impact.name);
                    System.out.println("- 影响分类: " + (impact.category != null ? impact.category : "未分类"));
										System.out.println("- 总影响值: " + totalValue + " " + impact.referenceUnit);

                    // 构建并展示三层级影响贡献树
                    System.out.println("\n===== 构建三层级影响贡献树 =====");

                    try {
                        // 1. 创建根节点 (使用public的rootsOf方法)
                        List<TreeItem> roots = TreeItem.rootsOf(result, List.of(impact));
                        if (!roots.isEmpty()) {
                            TreeItem root = roots.get(0);
                                System.out.println("\n[层级1] 根节点:");
                            System.out.println("  影响类别: " + impact.name);
                            System.out.println("  影响分类: " + (impact.category != null ? impact.category : "未分类"));
                            System.out.printf("  总影响值: %.4f %s, 贡献比例: %.2f%%\n",
                                    root.impactResult(), impact.referenceUnit,
                                    root.contributionShare() * 100);

                            // 2. 获取技术流内部节点（前5个）
                            // 使用正确的方式获取技术流，避免使用不存在的toList方法
                            List<TechFlow> techFlows = new ArrayList<>();
                            for (TechFlow techFlow : result.provider().techIndex()) {
                                techFlows.add(techFlow);
                                if (techFlows.size() >= 10) break; // 限制数量以提高性能
                            }

                            if (!techFlows.isEmpty()) {
                                List<TreeItem> techNodes = root.techNodesOf(techFlows, 0.01); // 1%的阈值
                                System.out.println("\n[层级2] 技术流内部节点:");
                                for (int i = 0; i < techNodes.size(); i++) {
                                    TreeItem node = techNodes.get(i);
                                    System.out.printf("  %d. 技术流: %s - %s\n",
                                            i + 1,
                                            node.techFlow().provider().name,
                                            node.techFlow().flow().name);
                                    System.out.printf("     影响值: %.4f, 贡献比例: %.2f%%\n",
                                            node.impactResult(),
                                            node.contributionShare() * 100);

                                    // 3. 获取每个技术流的环境流叶子节点
                                    List<EnviFlow> enviFlowsForLeafs = new ArrayList<>();
                                    for (EnviFlow enviFlow : result.provider().enviIndex()) {
                                        enviFlowsForLeafs.add(enviFlow);

                                    }

                                    if (!enviFlowsForLeafs.isEmpty()) {
                                        List<TreeItem> enviLeafs = node.enviLeafsOf(enviFlowsForLeafs, 0.01); // 10%的阈值
                                        System.out.println("     [层级3] 环境流叶子节点:");
                                        for (int j = 0; j < enviLeafs.size(); j++) {
                                            TreeItem leaf = enviLeafs.get(j);
                                            if (leaf.enviFlow() != null && leaf.enviFlow().flow() != null) {
                                                System.out.printf("       %d. 环境流: %s\n",
                                                        j + 1,
                                                        leaf.enviFlow().flow().name);
                                                System.out.printf("          影响值: %.4f, 贡献比例: %.2f%%\n",
                                                        leaf.impactResult(),
                                                        node.impactResult() != 0 ?
                                                                (leaf.impactResult() / node.impactResult()) * 100 : 0);
                                            }
                                        }
                                    }
                                }
                            }

                            // 也可以从根节点直接获取环境流内部节点
//                            System.out.println("\n[层级2] 环境流内部节点 (前5个):");
//                            List<EnviFlow> enviFlowsForNodes = new ArrayList<>();
//                            for (EnviFlow enviFlow : result.provider().enviIndex()) {
//                                enviFlowsForNodes.add(enviFlow);
//                                if (enviFlowsForNodes.size() >= 10) break;
//                            }
//
//                            if (!enviFlowsForNodes.isEmpty()) {
//                                List<TreeItem> enviNodes = root.enviNodesOf(enviFlowsForNodes, 0.01); // 1%的阈值
//                                for (int i = 0; i < Math.min(5, enviNodes.size()); i++) {
//                                    TreeItem node = enviNodes.get(i);
//                                    if (node.enviFlow() != null && node.enviFlow().flow() != null) {
//                                        System.out.printf("  %d. 环境流: %s\n",
//                                                i + 1,
//                                                node.enviFlow().flow().name);
//                                        System.out.printf("     影响值: %.4f, 贡献比例: %.2f%%\n",
//                                                node.impactResult(),
//                                                node.contributionShare() * 100);
//
//                                        // 获取每个环境流的技术流叶子节点（前3个）
//                                        List<TechFlow> techFlowsForLeafs = new ArrayList<>();
//                                        for (TechFlow techFlow : result.provider().techIndex()) {
//                                            techFlowsForLeafs.add(techFlow);
//                                            if (techFlowsForLeafs.size() >= 10) break;
//                                        }
//
//                                        if (!techFlowsForLeafs.isEmpty()) {
//                                            List<TreeItem> techLeafs = node.techLeafsOf(techFlowsForLeafs, 0.1); // 10%的阈值
//                                            System.out.println("     [层级3] 技术流叶子节点 (前3个):");
//                                            for (int j = 0; j < Math.min(3, techLeafs.size()); j++) {
//                                                TreeItem leaf = techLeafs.get(j);
//                                                if (leaf.techFlow() != null && leaf.techFlow().provider() != null && leaf.techFlow().flow() != null) {
//                                                    System.out.printf("       %d. 技术流: %s - %s\n",
//                                                            j + 1,
//                                                            leaf.techFlow().provider().name,
//                                                            leaf.techFlow().flow().name);
//                                                    System.out.printf("          影响值: %.4f, 贡献比例: %.2f%%\n",
//                                                            leaf.impactResult(),
//                                                            node.impactResult() != 0 ?
//                                                                    (leaf.impactResult() / node.impactResult()) * 100 : 0);
//                                                }
//                                            }
//                                        }
//                                    }
//                                }
//                            }
                        }

                    } catch (Exception e) {
                        System.out.println("构建贡献树时出错: " + e.getMessage());
                        e.printStackTrace();
                    }

//                    break; // 只处理第一个影响类别？
                }
            }

        } catch (Exception e) {
            fail("计算过程中发生错误: " + e.getMessage());
            e.printStackTrace();
        } finally {
            // 释放结果资源
            if (result != null) {
                result.dispose();
            }
        }
    }


}
